package com.chatplus.application.file.factory;

import com.chatplus.application.common.constant.GroupCacheNames;
import com.chatplus.application.common.exception.BadRequestException;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.util.CacheGroupUtils;
import com.chatplus.application.common.util.RedisUtils;
import com.chatplus.application.common.util.spring.SpringUtils;
import com.chatplus.application.file.constant.OssConstant;
import com.chatplus.application.file.core.OssClient;
import com.chatplus.application.file.exception.OssException;
import com.chatplus.application.file.properties.OssProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 文件上传Factory
 */

public class OssFactory {

    private OssFactory(){}

    static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(OssFactory.class);

    private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
    private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);

    /**
     * 获取默认实例
     */
    public static OssClient instance() {
        // 获取redis 默认类型
        String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);
        if (StringUtils.isEmpty(configKey)) {
            throw new OssException("文件存储服务类型无法找到!");
        }
        return instance(configKey);
    }

    /**
     * 根据类型获取实例
     */
    public static synchronized OssClient instance(String configKey) {
        String json = CacheGroupUtils.get(GroupCacheNames.SYS_OSS_CONFIG, configKey);
        if (json == null) {
            throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");
        }
        try {
            OssProperties properties = OBJECT_MAPPER.readValue(json, OssProperties.class);
            OssClient client = CLIENT_CACHE.get(configKey);
            if (client == null) {
                CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
                LOGGER.message("创建OSS实例").context("key", configKey).info();
                return CLIENT_CACHE.get(configKey);
            }
            // 配置不相同则重新构建
            if (!client.checkPropertiesSame(properties)) {
                CLIENT_CACHE.put(configKey, new OssClient(configKey, properties));
                LOGGER.message("重载OSS实例").context("key", configKey).info();
                return CLIENT_CACHE.get(configKey);
            }
            return client;
        } catch (Exception e) {
            LOGGER.message("根据类型获取实例").context("configKey",configKey).context("json", json).exception(e).error();
            throw new BadRequestException("系统异常, '" + configKey + "'配置信息不存在!");
        }
    }

}
